﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using nbb.darbo_grafikas.Properties;
using ewal.Data;
using ewal.Msg;

namespace nbb.darbo_grafikas
{
    static class DbCommunicator
    {
        internal static void fetchOperatoriai(List<Operatorius> storage)
        {
            string sql = "SELECT Operatoriai.Id, Operatoriai.Kodas, Operatoriai.Vardas ";
            sql += "FROM Operatoriai ";
            sql += "WHERE Operatoriai.Active=TRUE;";

            DataTable dt = DbHelper.FillDataTable(sql);
            foreach (DataRow dr in dt.Rows)
            {
                storage.Add(new Operatorius(dr));
            }
        }
        
        internal static void fetchDefektoskopai(List<Defektoskopas> storage)
        {
            string sql = "SELECT Defektoskopai.Id, Defektoskopai.Kodas, Defektoskopai.Gam_Nr, Defektoskopai.Gam_metai, DTipai.Pavadinimas AS Modelis ";
            sql += "FROM Defektoskopai INNER JOIN DTipai ON Defektoskopai.DTipai_Id = DTipai.Id ";
            sql += "WHERE (Defektoskopai.Active=TRUE) AND (DTipai.Istisines=TRUE);";

            DataTable dt = DbHelper.FillDataTable(sql);
            foreach (DataRow dr in dt.Rows)
            {
                storage.Add(new Defektoskopas(dr));
            }
        }

        internal static void fetchLinijos(List<Linija> storage)
        {
            string sql = "SELECT Linijos.Id, Linijos.Pavadinimas, Linijos.Kodas ";
            sql += "FROM Linijos ";
            sql += "WHERE Active=TRUE;";

            DataTable dt = DbHelper.FillDataTable(sql);
            foreach (DataRow dr in dt.Rows)
            {
                storage.Add(new Linija(dr));
            }
        }

        internal static void fetchStotys(List<Stotis> storage, int linijaid=0, int meistrijaid=0)
        {
            string sql = "SELECT Stotys.Id, Stotys.Pavadinimas, Stotys.Kodas, Meistrijos_Linijos.Meistrijos_Id, Meistrijos_Linijos.Linijos_Id ";
            sql += "FROM (Stotys INNER JOIN Stotys_MeistrijosLinijos ON Stotys.Id = Stotys_MeistrijosLinijos.Stotys_Id) INNER JOIN Meistrijos_Linijos ON Stotys_MeistrijosLinijos.Meistrijos_Linijos_Id = Meistrijos_Linijos.Id ";
            sql += "WHERE ";
            if (linijaid > 0)
                sql += string.Format("(Meistrijos_Linijos.Linijos_Id={0}) AND ", linijaid);
            if (meistrijaid > 0)
                sql += string.Format("(Meistrijos_Linijos.Meistrijos_Id={0}) AND ", meistrijaid);
            sql += "(Stotys.Active=TRUE);";

            DataTable dt = DbHelper.FillDataTable(sql);
            foreach (DataRow dr in dt.Rows)
            {
                storage.Add(new Stotis(dr));
            }
        }

        internal static void fetchMeistrijos(List<Meistrija> storage, int linijaid=0)
        {
            string sql = "SELECT Meistrijos.Id, Meistrijos.Pavadinimas, Meistrijos.Kodas, Meistrijos_Linijos.Linijos_Id AS Linijos_Id ";
            sql += "FROM Meistrijos INNER JOIN Meistrijos_Linijos ON Meistrijos.Id = Meistrijos_Linijos.Meistrijos_Id ";
            sql += "WHERE ";
            if (linijaid > 0)
                sql += string.Format("Meistrijos_Linijos.Linijos_Id={0} AND ", linijaid);
            sql += "Meistrijos.Active=TRUE AND Meistrijos_Linijos.Active=TRUE;";
            
            DataTable dt = DbHelper.FillDataTable(sql);
            foreach (DataRow dr in dt.Rows)
            {
                storage.Add(new Meistrija(dr));
            }
        }

        internal static void fetchKitiReikalai(List<KitasReikalas> storage)
        {
            string sql = "SELECT KitiReikalai.Id, KitiReikalai.Kodas, KitiReikalai.Pavadinimas ";
            sql += "FROM KitiReikalai ";
            sql += "WHERE KitiReikalai.Active=TRUE;";

            DataTable dt = DbHelper.FillDataTable(sql);
            foreach (DataRow dr in dt.Rows)
            {
                storage.Add(new KitasReikalas(dr));
            }
        }

        internal static void fetchIseigines(List<DateTime> storage, int grafikasid)
        {
            string sql = "SELECT Iseigines.Data ";
            sql += "FROM Iseigines ";
            sql += string.Format("WHERE Iseigines.Grafikai_Id={0} ORDER BY Iseigines.Data;", grafikasid);

            DataTable dt = DbHelper.FillDataTable(sql);
            foreach (DataRow dr in dt.Rows)
            {
                storage.Add((DateTime)dr["Data"]);
            }
        }

        internal static void fetchDarbaiByGrafikas(List<Darbas> storage, int grafikasid)
        {
            string sql = "SELECT * ";
            sql += "FROM Darbai ";
            sql += string.Format("WHERE Darbai.Grafikai_Id={0} ORDER BY Darbai.Data;", grafikasid);

            // delegate Defektoskopas returnDefektoskopasById(int id)
            // delegate Stotis returnStotisById(int id)
            // delegate Linija returnLinijaById(int id)
            // delegate Meistrija returnMeistrijaById(int id)


            DataTable dt = DbHelper.FillDataTable(sql);
            //Darbas darbas;
            foreach (DataRow dr in dt.Rows)
            {
                //storage.Add(new Darbas(dr));
                //darbas = new Darbas((DateTime)dr["Data"], new Defektoskopas);

            }
        }

        internal static int createNewSchedule(DateTime nuo, DateTime iki, string title, string description)
        {
            string preSql = "INSERT INTO Grafikai (Data_Nuo, Data_Iki, Pavadinimas, Aprasymas) VALUES ";
            preSql += "(#{0}#, #{1}#, '{2}', '{3}')";
            string sql = string.Format(preSql, Program.ShortDate(nuo),  Program.ShortDate(iki), title, description);
            DbHelper.ExecuteNonQuery(sql);
            string sql1 = "SELECT MAX(Id) FROM Grafikai";
            return (int)DbHelper.FetchSingleValue(sql1);
        }

        internal static string NiceDate(DateTime date)
        {
            // gražinti datą, priklausomai nuo dbprovaiderio
            return date.ToString("#yyyy-MM-dd#");
        }

        internal static void DeleteDarbaiByGrafikasId(int grafikasId)
        {
            string sqlDeleteDarbai = string.Format("DELETE FROM Darbai WHERE Grafikai_Id={0};", grafikasId);
            try
            {
                DbHelper.ExecuteNonQuery(sqlDeleteDarbai);
            }
            catch
            {
                new Exception("Nepavyko pašalinti darbų. Čia SQL: " + sqlDeleteDarbai);
            }
        }

        internal static void insertDarbai(List<Darbas> storage)
        {            
            foreach (Darbas darbas in storage)
            {
                //if (darbas.Id > 0)
                //    UpdateDarbas(darbas);
                //else
                    InsertDarbas(darbas);
            }
        }

        private static void InsertDarbas(Darbas darbas)
        {
            int justInsertedId;
            int resultCount = 0;
            string mainInsertSqlTemplate = "INSERT INTO Darbai {0} VALUES {1};";
            string insertDarbasColumnList = Darbas.InsertSqlColumnsList();
            string mainInsertSql;

            string lastInsertedIdSql = "SELECT MAX(Id) FROM Darbai;";
                        
            // įrašyti darbą
            mainInsertSql = string.Format(mainInsertSqlTemplate, insertDarbasColumnList, darbas.MainInsertSqlString());
            try
            {
                resultCount = DbHelper.ExecuteNonQuery(mainInsertSql);
            }
            catch
            {
                // pizė
                throw new Exception(Messages.Default.FailedInsertDarbas + mainInsertSql);
            }

            // sužinoti įrašyto darbo Id
            try
            {
                justInsertedId = (int)DbHelper.FetchSingleValue(lastInsertedIdSql);
            }
            catch
            {
                // pizė
                throw new Exception(string.Format(Messages.Default.FailedInsertOperators,
                                            darbas.Data.ToShortDateString(),
                                            darbas.Defektoskopas.Kodas,
                                            lastInsertedIdSql));
            }

            darbas.Id = justInsertedId;

            // Pririšti operatorius
            bindOperatoriaiToDarbas(darbas);

            //pririšti kitus reikalus
            bindKitiReikalaiToDarbas(darbas);
        }

        private static void UpdateDarbas(Darbas darbas)
        {
            int id = darbas.Id;
            int resultCount = 0;
            string mainUpdateSqlTemplate = "UPDATE Darbai SET {0} WHERE Id={1};";
            string mainUpdateSql = string.Format(mainUpdateSqlTemplate, darbas.MainUpdateSqlString(), id);
            try
            {
                resultCount = DbHelper.ExecuteNonQuery(mainUpdateSql);
            }
            catch
            {
                // pizė
                throw new Exception(string.Format(Messages.Default.FailedUpdateDarbas,
                                                    darbas.Data.ToShortDateString(),
                                                    darbas.Defektoskopas.Kodas,
                                                    mainUpdateSql));
            }

            // Pririšti operatorius
            bindOperatoriaiToDarbas(darbas);

            //pririšti kitus reikalus
            bindKitiReikalaiToDarbas(darbas);
        }

        private static void bindOperatoriaiToDarbas(Darbas darbas)
        {
            
            // Ištrinti operatorius
            string deleteOperatorsSql = string.Format("DELETE FROM Darbai_Operatoriai WHERE Darbai_Id={0};", darbas.Id);
            try
            {
                DbHelper.ExecuteNonQuery(deleteOperatorsSql);
            }
            catch
            {
                // pizė
                throw new Exception(string.Format(Messages.Default.FailedUpdateOperatorList,
                                                    darbas.Data.ToShortDateString(),
                                                    darbas.Defektoskopas.Kodas,
                                                    deleteOperatorsSql));
            }

            // Pririšti operatorius

            string insertOperatorSql = "INSERT INTO Darbai_Operatoriai (Darbai_Id, Operatoriai_Id) VALUES ({0}, {1});";            

            foreach (Operatorius operatorius in darbas.OperatoriuSarasas)
            {
                try
                {
                    DbHelper.ExecuteNonQuery(string.Format(insertOperatorSql, darbas.Id, operatorius.Id));
                }
                catch
                {
                    // pizė
                    Msg.ErrorMsg(string.Format(Messages.Default.FailedInsertOperators,
                                                darbas.Data.ToShortDateString(),
                                                darbas.Defektoskopas.Kodas,
                                                string.Format(insertOperatorSql, darbas.Id, operatorius.Id)));
                    return;
                }
            }           
        }

        private static void bindKitiReikalaiToDarbas(Darbas darbas)
        {

            // Ištrinti kitus reikalus
            string deleteKRsSql = string.Format("DELETE FROM Darbai_KitiReikalai WHERE Darbai_Id={0};", darbas.Id);
            try
            {
                DbHelper.ExecuteNonQuery(deleteKRsSql);
            }
            catch
            {
                // pizė
                throw new Exception(string.Format(Messages.Default.FailedUpdateOperatorList,
                                                    darbas.Data.ToShortDateString(),
                                                    darbas.Defektoskopas.Kodas,
                                                    deleteKRsSql));
            }

            // Pririšti kitus reikalus
            string insertKRSql = "INSERT INTO Darbai_KitiReikalai (Darbai_Id, KitiReikalai_Id) VALUES ({0}, {1});";

            foreach (KitasReikalas kr in darbas.KituReikaluSarasas)
            {
                try
                {
                    DbHelper.ExecuteNonQuery(string.Format(insertKRSql, darbas.Id, kr.Id));
                }
                catch
                {
                    // pizė
                    Msg.ErrorMsg(string.Format(Messages.Default.FailedInsertKRs,
                                                darbas.Data.ToShortDateString(),
                                                darbas.Defektoskopas.Kodas,
                                                string.Format(insertKRSql, darbas.Id, kr.Id)));
                    return;
                }
            }            
        }
    }


}
